/***************************************************************************
 *   Copyright (C) 2016 by Peter Shieh                                     *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#ifndef USB_COMMON_H
#define USB_COMMON_H


typedef unsigned char 	BYTE;

#if defined(_MSC_VER) && (_MSC_VER < 1600) && (!defined(_STDINT)) && (!defined(_STDINT_H))
typedef unsigned __int8   uint8_t;
typedef unsigned __int16  uint16_t;
typedef unsigned __int32  uint32_t;
#else
#include <stdint.h>
#include <stdarg.h>
#endif


#ifndef STANDALONE
// the openOCD version
#include <stdbool.h>
#include <helper/log.h>


#else
// standalone version

#ifdef TDEBUG
#define LOGMSG(args) (printf("EVK: %s line:%d ", __FILE__, __LINE__), printf args, printf ("\n"))
#else
#define LOGMSG(args) 
#endif

// using diff macro style which matches with all our other debugging macro

#define LOG_USER(args...)  printf(args), printf("\n")
#define LOG_INFO(args...)  LOGMSG((args))
#define LOG_DEBUG(args...) LOGMSG((args))
#define LOG_ERROR(args...) LOGMSG((args))

#define ERROR_OK 		(0)
#define ERROR_FAIL		(-1)

#if !defined(bool)
#define bool int
#endif
#if !defined(true)
#define true (1 == 1)
#endif
#if !defined(false)
#define false (!true)
#endif



#endif // STANDALONE

#include <libusb.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define tlink_libusb_device					libusb_device
#define tlink_libusb_device_descriptor		libusb_device_descriptor
#define tlink_libusb_interface				libusb_interface
#define tlink_libusb_interface_descriptor	libusb_interface_descriptor
#define tlink_libusb_endpoint_descriptor	libusb_endpoint_descriptor
#define tlink_libusb_config_descriptor		libusb_config_descriptor
#define tlink_libusb_reset_device(dev)		libusb_reset_device(dev)
#define tlink_libusb_get_device(devh)		libusb_get_device(devh)

#define libusb_device_handle							libusb_device_handle

extern libusb_device_handle  * tlink_dev;

libusb_device_handle  * tlink_usb_open();

void tlink_debug_buffer(const uint8_t * buffer, int length);
int tlink_usb_control_read(libusb_device_handle  * tlink, uint16_t deviceAddress, 
	uint16_t length, uint8_t *writeBuffer, int * actual);
int tlink_usb_control_write(libusb_device_handle  * tlink, uint16_t deviceAddress,
	 uint16_t length, uint8_t * writeBuffer) ;
void tlink_usb_close();


static inline int tlink_libusb_claim_interface(libusb_device_handle *devh, int iface)
{
	return libusb_claim_interface(devh, iface);
};

static inline int tlink_libusb_release_interface(libusb_device_handle *devh, int iface)
{
	return libusb_release_interface(devh, iface);
}

int tlink_libusb_open(const uint16_t vids[], const uint16_t pids[], const char *serial, libusb_device_handle **out);
void tlink_libusb_close(libusb_device_handle *dev);
int tlink_libusb_control_transfer(libusb_device_handle *dev, uint8_t requestType, uint8_t request, uint16_t wValue,
		uint16_t wIndex, char *bytes,	uint16_t size, unsigned int timeout);
int tlink_libusb_set_configuration(libusb_device_handle *devh, int configuration);

#endif 
